home *** CD-ROM | disk | FTP | other *** search
- /* cat > headers/wildcard.h << "EOF" */
- /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- /* wildcard.h: header for wildcard.c file */
- /* The wildcard routine takes an input */
- /* wildcard pattern and returns a vector of */
- /* filename strings that match the given */
- /* wildcard pattern. The returned vector */
- /* ends with a NULL pointer. Output strings */
- /* are sorted in lexicographical order. The */
- /* malloc function is called to allocate */
- /* temporary space for the returned */
- /* 2-dimension character array. In case */
- /* anything goes wrong, a char pointer */
- /* that contains NULL is returned. */
- /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- /* SCCS information: %W% %G% - NCSA */
-
- #define wildcard_h 1
-
- #include "all.h"
- #include "newext.h"
-
- static struct argnod *gchain;
- static char *entry;
- static char *buffer, *bufptr;
- static char *nullname[1];
-
- /* EOF */
- /* cat > src+obj/wildcard/addg.c << "EOF" */
- /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- /* addg: The addg adds the string of concatinating */
- /* "as1""as2"'/'"++as3" at the end of the global */
- /* list headed by gchain. */
- /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- /* SCCS information: %W% %G% - NCSA */
-
- /* #include "wildcard.h" */
-
- addg (as1, as2, as3)
- char *as1, *as2, *as3;
- {
- register char *s1, *s2;
- register int c;
- struct argnod *args, *rchain;
-
- args = (struct argnod *) bufptr;
- args->argnxt = NULL;
- if (gchain != NULL)
- {
- rchain = gchain;
- while (rchain->argnxt != NULL)
- rchain = rchain->argnxt;
- rchain->argnxt = args;
- }
- else
- {
- gchain = args;
- }
-
- s2 = args->argval;
- s1 = as1;
- while (c = *s1++)
- {
- if ((c &= STRIP) == 0)
- {
- *s2++ = '/';
- break;
- }
- *s2++ = c;
- }
- s1 = as2;
- while (*s2 = *s1++)
- s2++;
- if (s1 = as3)
- {
- *s2++ = '/';
- while (*s2++ = *++s1);
- }
- bufptr += strlen (args->argval) + sizeof (args->argnxt) + BYTESPERWORD;
- bufptr = (char *) ((unsigned) bufptr & ~(BYTESPERWORD - 1));
- }
- /* EOF */
- /* cat > src+obj/wildcard/gbrace.c << "EOF" */
- /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- /* gbrace: The gbrace routine splits braces into */
- /* different patterns and puts them in a list */
- /* (gchain is the head pointer). It returns 0 */
- /* when no braces found, -1 when syntax error */
- /* or a count indicates how many patterns have */
- /* been generated. */
- /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- /* SCCS information: %W% %G% - NCSA */
-
- /* #include "wildcard.h" */
-
- gbrace (s1)
- char *s1;
- {
- char *sp, *tp;
- char s2[MAXNAMLEN + 1];
- char s3[MAXNAMLEN + 1];
- int i, cnt = 0;
-
- sp = s1;
- while (*sp != '{')
- {
- if (*sp == '\0')
- {
- return (0);
- }
- sp++;
- }
- tp = s2;
- *sp = '\0';
- while (*++sp != '}')
- {
- if (*sp == ' ' || *sp == '\t' || *sp == '\0')
- {
- return (-1);
- }
- if (*sp == ',')
- {
- cnt++;
- *tp++ = '\0';
- }
- else
- *tp++ = *sp;
- }
- cnt++;
- *tp = '\0';
- tp = s2;
- ++sp;
- for (i = 0; i < cnt; i++)
- {
- strcpy (s3, tp);
- addg (s1, strcat (s3, sp), NULL);
- tp += strlen (tp) + 1;
- }
- return (cnt);
- }
- /* EOF */
- /* cat > src+obj/wildcard/gexpand.c << "EOF" */
- /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- /* gexpand: This subroutine expands wildcard pattern */
- /* string, i.e. as, into a filename list */
- /* headed by gchain. The number of filenames */
- /* found is returned. */
- /* "*" in a pattern matches r.e "c*" */
- /* "?" in a pattern matches r.e. "c" */
- /* "[...]" in a pattern matches character */
- /* class */
- /* "[...a-z...]" in a pattern matches a */
- /* through z. */
- /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- /* SCCS information: %W% %G% - NCSA */
-
- /* #include "wildcard.h" */
-
- gexpand (as)
- char *as;
- {
- register char *s, *cs;
- int count = 0;
- DIR *dirp;
- bool left = 0;
- char *rescan = NULL;
- struct argnod *schain = gchain;
-
- s = cs = as;
-
- /* check for meta chars */
- for (;;)
- {
- switch (*cs++)
- {
- case '/':
- left = 0;
- continue;
- case '[':
- left++;
- continue;
- case ']':
- if (left == 0)
- continue;
- case '?':
- case '*':
- case '\0':
- cs--;
- break;
- default:
- continue;
- }
- break;
- }
-
- /* find the prefix that needs not be expanded */
- for (;;)
- {
- if (cs == s)
- {
- s = "";
- break;
- }
- else if (*--cs == '/')
- {
- *cs = '\0';
- if (s == cs)
- s = "/";
- break;
- }
- }
-
- dirp = opendir (*s ? s : ".");
- if (*cs == '\0')
- *cs++ = 0200;
-
- if (dirp != NULL)
- { /* open directory succeed */
- register char *rs;
- struct direct *e;
-
- /* check for rescan */
- rs = cs;
- do
- {
- if (*rs == '/')
- {
- rescan = rs;
- *rs = '\0';
- gchain = NULL;
- }
- } while (*rs++);
-
- /* match all dir entries */
- while (e = readdir (dirp))
- {
- strcpy (entry, e->d_name);
- if (entry[0] == '.' && *cs != '.')
- continue;
- if (gmatch (entry, cs))
- {
- addg (s, entry, rescan);
- count++;
- }
- }
- closedir (dirp);
-
- /* not the last dir, recursively matche the rest */
- if (rescan)
- {
- register struct argnod *rchain;
-
- rchain = gchain;
- gchain = schain;
- if (count)
- {
- count = 0;
- while (rchain)
- {
- count += gexpand (rchain->argval);
- rchain = rchain->argnxt;
- }
- }
- *rescan = '/';
- }
- }
-
- /* restore all 0200's back to slash char */
- {
- register char c;
-
- s = as;
- while (c = *s)
- *s++ = (c & STRIP ? c : '/');
- }
- return (count);
- }
- /* EOF */
- /* cat > src+obj/wildcard/gmatch.c << "EOF" */
- /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- /* gmatch: The function gmatch is to match string s */
- /* with the regular expression patter p. The */
- /* string s is usually a file name in a */
- /* directory file, which does not contain the */
- /* slash ('/') character. The function returns */
- /* zero (0) if s and p do not match; returns */
- /* non-zero otherwise. */
- /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- /* SCCS information: %W% %G% - NCSA */
-
- /* #include "wildcard.h" */
-
- gmatch (s, p)
- register char *s, *p;
- {
- register scc;
- char c;
- bool ok = 0;
- int lc = 077777;
- int notflag = 0;
-
- if (scc = *s++)
- {
- if ((scc &= STRIP) == 0)
- scc = 0200;
- }
- switch (c = *p++)
- {
- case '[':
- if (*p == '!')
- {
- notflag = 1;
- p++;
- }
- while (c = *p++)
- {
- if (c == ']')
- return (ok ? gmatch (s, p) : 0);
- else if (c == '-')
- {
- if (notflag)
- {
- if (scc < lc || scc > *(p++))
- ok++;
- else
- return (0);
- }
- else if (lc <= scc && scc <= (*p++))
- ok++;
- }
- else
- {
- lc = c & STRIP;
- if (notflag)
- {
- if (scc && scc != lc)
- ok++;
- else
- return (0);
- }
- else if (scc == lc)
- ok++;
- }
- }
- return (0);
- default:
- if ((c & STRIP) != scc)
- return (0);
- case '?':
- return (scc ? gmatch (s, p) : 0);
- case '*':
- while (*p == '*')
- p++;
- if (*p == 0)
- return (1);
- --s;
- while (*s)
- {
- if (gmatch (s++, p))
- return (1);
- }
- return (0);
- case '\0':
- return (scc == 0);
- }
- }
- /* EOF */
- /* cat > src+obj/wildcard/gsort.c << "EOF" */
- /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- /* gsort: The shell sorting routine */
- /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- /* SCCS information: %W% %G% - NCSA */
-
- /* #include "wildcard.h" */
-
- gsort (from, to)
- char *from[], *to[];
-
- {
- int k, m, n;
- register int i, j;
-
- if ((n = to - from) <= 1)
- return;
- for (j = 1; j <= n; j *= 2);
- for (m = 2 * j - 1; m /= 2;)
- {
- k = n - m;
- for (j = 0; j < k; j++)
- {
- for (i = j; i >= 0; i -= m)
- {
- register char **fromi;
-
- fromi = &from[i];
- if (strcmp (fromi[m], fromi[0]) > 0)
- {
- break;
- }
- else
- {
- char *s;
-
- s = fromi[m];
- fromi[m] = fromi[0];
- fromi[0] = s;
- }
- }
- }
- }
- }
- /* EOF */
- /* cat > src+obj/wildcard/wildcard.c << "EOF" */
- /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- /* wildcard: main wildcard routine. Error number */
- /* returned for handling elsewhere. */
- /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
- /* SCCS information: %W% %G% - NCSA */
-
- /* BUG: 1. Can't handle path = / properly!
- Workaround: Add a period to the end. */
-
- /* #include "wildcard.h" */
-
- char **
- wildcard (p, err)
- char *p; /* input */
- int *err; /* returns = 0 - No error.
- 1 - Syntax error.
- 2 - Memory allocation error */
- {
- int i, count = 0, bufsz = 0;
- char c, *ss, *sp;
- char **name;
- char string[MAXNAMLEN + 1];
- register struct argnod *rchain, *schain;
- char *getenv ();
-
- char stack_entry[MAXNAMLEN+1];
- char stack_buffer[BUFFERSIZ];
-
- *err = 0;
-
- nullname[0] = NULL;
- gchain = NULL;
- entry = stack_entry;
- buffer = stack_buffer;
-
- /* entry = (char *) alloca (MAXNAMLEN+1);
- if ((buffer = (char *) alloca (BUFFERSIZ)) == NULL)
- {
- *err = 2;
- return (nullname);
- }*/
- bufptr = buffer + (BYTESPERWORD - 1);
- bufptr = (char *) ((unsigned) bufptr & ~(BYTESPERWORD - 1));
-
- /* eliminate starting and trailing white space */
- while (*p == ' ' || *p == '\t')
- p++;
- if ((i = strlen (p)) == 0)
- return (nullname);
- do
- {
- p[i--] = '\0';
- } while (p[i] == ' ' || p[i] == '\t');
-
- /* eliminate trailing /'s except for the first */
- i++;
- do
- {
- p[i--] = '\0';
- } while (p[i] == '/' && i > 0);
-
- /* BUG workaround: Add a period to fix the / problem */
- if ( p[i] == '/')
- {
- p[++i] = '.';
- p[++i] = '\0';
- }
-
- /* handle the case speciall
- /* printf */
- /* sprintf (wkstr2, "p = %s", p);
- msg_write (wkstr2); */
-
- /* handle multiple brace pairs in a loop */
-
- addg (p, "", NULL);
- do
- {
- rchain = gchain;
- gchain = NULL;
- while (rchain != NULL)
- {
- switch (gbrace (rchain->argval))
- {
- case -1:
- *err = 1;
- return (nullname);
- case 0:
- break;
- default:
- rchain = rchain->argnxt;
- continue;
- }
- break;
- }
- } while (gchain != NULL);
-
- /* input pattern could really be a list because of braces
- the following loop processes one pattern at a time */
- schain = rchain;
- do
- {
- int rval;
-
- string[0] = '\0';
- ss = rchain->argval;
-
- /* substitute ~[user] with an appropriate home dir */
- if (*ss == '~')
- {
- if (isalpha (*++ss))
- {
- struct passwd *pp;
-
- sp = ss;
- while (isalpha (*++ss));
- c = *ss;
- *ss = '\0';
- if ((pp = getpwnam (sp)) == NULL)
- return (nullname);
- *ss = c;
- strcpy (string, pp->pw_dir);
- }
- else
- {
- if ((sp = getenv ("HOME")) == NULL)
- return (nullname);
- strcpy (string, sp);
- }
- if (*ss != '/' && *ss != '\0')
- return (nullname);
- }
-
- /* do the real expansion and the results are appended
- to a list headed by gchain */
- rval = gexpand (strcat (string, ss));
-
- /* remember the count for each pattern which is used
- for sorting with groups */
- count += rval;
- rchain->argval[0] = rval;
- } while ((rchain = rchain->argnxt) != NULL);
-
- /* allocate tmp space for output */
- name = (char **) calloc (count + 1, sizeof (char *));
- if (name == NULL)
- {
- *err = 2;
- return (nullname);
- }
- rchain = gchain;
- for (i = 0; i < count; i++)
- {
- bufsz += strlen (rchain->argval) + 1;
- rchain = rchain->argnxt;
- }
- bufptr = (char *) malloc (bufsz);
- if (bufptr == NULL)
- {
- *err = 2;
- return (nullname);
- }
-
- /* copy the matched strings to the output buffer */
- rchain = gchain;
- for (i = 0; i < count; i++)
- {
- name[i] = bufptr;
- strcpy (name[i], rchain->argval);
- bufptr += strlen (name[i]) + 1;
- rchain = rchain->argnxt;
- }
- name[count] = NULL;
-
- /* sort the output strings group by group */
- rchain = schain;
- i = 0;
- do
- {
- int j;
-
- j = i + (int) rchain->argval[0];
- gsort (&name[i], &name[j]);
- i = j;
- rchain = rchain->argnxt;
- } while (rchain != NULL);
-
- return (name);
- }
- /* EOF */
-